import React from 'react'
import {NavBar, Icon, Toast} from 'antd-mobile'
import './index.scss'

// 导入封装的ajax
import request from '../../utils/api.js'

import 'react-virtualized/styles.css'
import {List, AutoSizer} from 'react-virtualized'

// 引入地图当前位置封装的组件
import getCurrentCity from '../../utils/localtion.js'

class CityList extends React.Component {

    // ------------------------------数据部分----------------------------------

    state = {
        // 当前选中的索引
        activeIndex: 0,
        // 列表城市数据
        cityList: []
    }

    // 创建一个List组件的引用
    listRef = React.createRef()

    // 刚进页面时发送ajax请求数据钩子函数
    componentDidMount() {
        // 组件开始加载时进行提示
        Toast.loading('正在加载...', 0, null, false)
        // 城市列表
        this.loadData()
    }

    // ------------------------------发送ajax部分----------------------------------

    // 获取城市列表数据
    loadData = async () => {
        let res = await request({
            method: 'get',
            url: '/area/city',
            params: {
                level: 1
            }
        })
        // 对原始列表进行重构
        let ret = this.formatData(res.body)
        // 添加一线城市
        const hot = await request({
            method: 'get',
            url: '/area/hot'
        })
        ret.cityIndex.unshift('热门城市')
        ret.cityList['热门城市'] = hot.body

        // 通过地理定位获取当前城市名称
        let ccity = await getCurrentCity()
        ret.cityIndex.unshift('#')
        ret.cityList['#'] = [ccity]
        this.setState({
            cityList: ret
        }, () => {
            // 提前计算列表总高度
            this.listRef.current.measureAllRows()
        })
        // 隐藏加载提示
        Toast.hide()
    }

    // ------------------------------布局方法部分----------------------------------

    // 头部导航
    renderNavbar = () => {
        return (
            <NavBar
                mode="light"
                icon={<Icon type="left"/>}
                onLeftClick={() => {
                    // 返回到主页 =》 三种方法都可实s现返回到上一级
                    // this.prodps.history.push('/home')
                    // this.props.history.goBack()
                    this.props.history.go(-1)
                }}
            >
                城市选择
            </NavBar>
        )
    }

    // 把原始数据进行重构 => 进行排序
    formatData = (list) => {
        // 最终处理的结果
        let result = {}
        // 所有的key
        let allIndex = []
        list.forEach(item => {
            // 获取城市的首字母
            let firstLetter = item.short.substr(0, 1)
            if (result.hasOwnProperty(firstLetter)) {
                // 已存在，直接添加到数组
                result[firstLetter].push(item)
            } else {
                // 不存在，初始化数据
                result[firstLetter] = [item]
            }
        })
        // 对索引进行排序 =》 根据对象的键进行数组中对象的排序
        allIndex = Object.keys(result).sort()
        return {
            cityList: result,
            cityIndex: allIndex
        }
    }

    // 动态生成城市列表模板  =》 之前传统做法没有列表优化
    // renderCityList = () => {
    //     let {cityList, cityIndex} = this.state.cityList
    //     let cityTag = []
    //     cityIndex && cityIndex.forEach(k => {
    //         // 获取每个条目的标题字符：k
    //         cityTag.push(<div key={k}>{k}</div>)
    //         // 获取其中一项数据:城市列表数据
    //         let city = cityList[k]
    //         // 遍历城市列表数据
    //         city.forEach(c => {
    //             cityTag.push(<div key={c.value}>{c.label}</div>)
    //         })
    //     })
    //     return cityTag
    // }

    // 渲染每一个列表条目模板
    rowRenderer = ({key, style, index}) => {
        // key 表示每一行唯一标识
        // style 应用于行的样式，实现定位
        // index 表示列表行的索引
        let {cityList, cityIndex} = this.state.cityList
        // 根据当前行数据的索引获取分组标题的字符
        let firstLetter = cityIndex[index]
        // 根据分组索引字符获取对应的城市列表数据
        let cities = cityList[firstLetter]
        // 城市列表的模板
        const cityTag = cities.map(item => (
            <div
                onClick={() => {
                    // 只允许选择一线城市
                    if (['北京', '上海', '广州', '深圳'].includes(item.label)) {
                        // 百度地图中有一个API：根据城市名称获取他的经纬度
                        let geo = new window.BMap.Geocoder()
                        geo.getPoint(item.label, (data) => {
                            console.log(item.label, data)
                            let info = {
                                label: item.label,
                                value: item.value,
                                lng: data && data.lng,
                                lat: data && data.lat
                            }
                        // 点击后，保存到本地缓存
                        window.localStorage.setItem(
                            'hkzf_city', JSON.stringify(info))
                        // 返回首页
                        this.props.history.push('/home')
                        },'中国')
                    } else {
                        // 提示信息
                        Toast.info('只允许选择一线城市...', 1, null, false)
                    }
                }}
                key={item.value} className="name">{item.label}
            </div>
        ))
        return (
            <div key={key} style={style} className="row-city">
                <div className="title">{firstLetter.toUpperCase()}</div>
                {cityTag}
            </div>
        )
    }

    // 动态计算列表每一行高度
    calcRowHeight = ({index}) => {
        // index表示当前行数据的索引
        let {cityIndex, cityList} = this.state.cityList
        // 根据数据索引获取分组标题的字符
        let firstLetter = cityIndex[index]
        // 根据标题索引获取当前行的城市列表数据
        let cities = cityList[firstLetter]
        // 行高计算公式：标题的高度 + 每个城市的高度 * 城市的数量
        return 36 + 50 * cities.length
    }

    // 动态填充右侧索引
    renderRightIndex = () => {
        const {cityIndex} = this.state.cityList
        const {activeIndex} = this.state
        return cityIndex && cityIndex.map((item, index) => (
            <li
                onClick={() => {
                    // 控制列表滚动
                    this.listRef.current.scrollToRow(index)
                }}
                key={index}
                className="city-index-item">
        <span className={activeIndex === index ? 'index-active' : ''}>
          {item === '热门城市' ? '热' : item.toUpperCase()}
        </span>
            </li>
        ))
    }

    // 监听列表的滚动行为
    onRowsRendered = ({startIndex}) => {
        if (this.state.activeIndex !== startIndex) {
            if (startIndex === 19) {
                // 如果滚动到底部时，无法让Z高亮，就固定给设置一个值
                startIndex = 20
            }
            this.setState({
                activeIndex: startIndex
            })
        }
    }

    // ------------------------------调用显示部分----------------------------------

    render() {
        // 获取列表的真实数据
        let {cityList, cityIndex} = this.state.cityList
        return (
            <div className='city'>
                {/*头部导航*/}
                {this.renderNavbar()}
                {/*城市列表*/}
                {/*{this.renderCityList()}*/}
                {cityIndex && <AutoSizer>
                    {({height, width}) => (
                        <List
                            ref={this.listRef}
                            className='city'
                            onRowsRendered={this.onRowsRendered}
                            scrollToAlignment='start'
                            width={width}
                            height={height - 45}
                            rowCount={cityIndex.length}
                            rowHeight={this.calcRowHeight}
                            rowRenderer={this.rowRenderer}
                        />
                    )}
                </AutoSizer>}
                {/*右侧索引*/}
                <ul className="city-index">
                    {this.renderRightIndex()}
                </ul>
            </div>
        )
    }
}

export default CityList